/* ================================================================ */
/* protect.h                                                        */
/* Usage: Structure and const define for protect mode used.         */
/* Create Date: 2007-01-18                                          */
/* Creator: MaJiuyue                                                */
/* ================================================================ */

#ifndef	_PROTECT_H_
#define	_PROTECT_H_

#include <type.h>

// GDT/LDT descriptor
struct DESCRIPTOR
{
	u16	limit_low;              // Limit
	u16	base_low;               // Base
	u8	base_mid;               // Base
	u8	attr1;                  // P(1) DPL(2) DT(1) TYPE(4)
	u8	limit_high_attr2;       // G(1) D(1) 0(1) AVL(1) LimitHigh(4)
	u8	base_high;              // Base
};
// Methods for make GDT/LDT descriptor
#define MAKE_DESCRIPTOR(base, limit, attr)                             \
   { (limit) & 0xFFFF, (base)&0xFFFF, ((base)>>16)&0xFF, (attr)&0xFF,  \
     (((limit)>>16)&0xF)|((attr)>>8)&0xF0, ((base)>>24)&0xFF } 
// GDT Pointer
struct GDTPointer {
	u16 limit;	// GDT Limit
	u32 base;	// GDT Base
} __attribute__((packed));


// Gate descriptor
struct GATE
{
	u16	offset_low;		// Offset Low
	u16	selector;		// Selector
	u8	dcount;		
	u8	attr;			// P(1) DPL(2) DT(1) TYPE(4)
	u16	offset_high;	// Offset High
};

// PD/PT entry
#define PG_PRESENT		1
#define PG_RW			2
#define PG_US			4
#define PG_PWT			8
#define PG_DISCACHE		16
#define PG_ACCESSED		32
#define PG_DIRTY		64
#define PG_PAGESIZE		128
#define PG_GLOBAL		256
#define PG_BASE_MASK	0xFFFFF000


#define IO_BITMAP_SIZE 129
// Task status segment structure
struct TSS {
	u32	backlink;
	u32	esp0;		// stack pointer to use during interrupt
	u32	ss0;		//   "   segment  "  "    "        "    
	u32	esp1;
	u32	ss1;
	u32	esp2;
	u32	ss2;
	u32	cr3;
	u32	eip;
	u32	flags;
	u32	eax;
	u32	ecx;
	u32	edx;
	u32	ebx;
	u32	esp;
	u32	ebp;
	u32	esi;
	u32	edi;
	u32	es;
	u32	cs;
	u32	ss;
	u32	ds;
	u32	fs;
	u32	gs;
	u32	ldt;
	u16	trap;
	u16	iobase;
	u8  io_bitmap[IO_BITMAP_SIZE];   // io ports arrange from 0x0 to 0x3FF
};

// GDT Index
#define	INDEX_DUMMY			0x0
#define	INDEX_KERNEL_C			0x1
#define	INDEX_KERNEL_RW			0x2
#define	INDEX_4G_RW			0x3
#define INDEX_TSS			0x4
#define INDEX_LDT			0x5
#define INDEX_USER_C			0x6

// GDT Selector
#define	SELECTOR_DUMMY			0x0		
#define	SELECTOR_KERNEL_C		0x08		
#define	SELECTOR_KERNEL_RW		0x10
#define SELECTOR_4G_RW			0x18
#define SELECTOR_TSS			0x20
#define SELECTOR_LDT			0x28
#define SELECTOR_USER_C			0x30

// LDT Index
#define LDT_INDEX_USER_C		0x0
#define LDT_INDEX_USER_RW		0x1
#define LDT_INDEX_CALLGATE		0x2

// LDT Selector
#define SELECTOR_LDT_USER_C		0x4
#define SELECTOR_LDT_USER_RW		0xC
#define SELECTOR_LDT_CALLGATE		0x14


#define	DA_32					0x4000
#define	DA_LIMIT_4K				0x8000
#define	DA_DPL0					0x00	// DPL = 0
#define	DA_DPL1					0x20	// DPL = 1
#define	DA_DPL2					0x40	// DPL = 2
#define	DA_DPL3					0x60	// DPL = 3
#define	DA_DR					0x90
#define	DA_DRW					0x92
#define	DA_DRWA					0x93
#define	DA_C					0x98
#define	DA_CR					0x9A
#define	DA_CCO					0x9C
#define	DA_CCOR					0x9E
#define	DA_LDT					0x82	// LDT
#define	DA_TaskGate				0x85	// 16 bit TaskGate
#define	DA_386TSS				0x89	// 386 TSS
#define	DA_386CGate				0x8C	// 386 CallGate
#define	DA_386IGate				0x8E	// 386 InterruptGate
#define	DA_386TGate				0x8F	// 386 TaskGate


#define	SA_RPL_MASK				0xFFFC
#define	SA_RPL0					0
#define	SA_RPL1					1
#define	SA_RPL2					2
#define	SA_RPL3					3
#define	SA_TI_MASK				0xFFFB
#define	SA_TIG					0
#define	SA_TIL					4


#define	INT_VECTOR_DIVIDE			0x0
#define	INT_VECTOR_DEBUG			0x1
#define	INT_VECTOR_NMI				0x2
#define	INT_VECTOR_BREAKPOINT			0x3
#define	INT_VECTOR_OVERFLOW			0x4
#define	INT_VECTOR_BOUNDS			0x5
#define	INT_VECTOR_INVAL_OP			0x6
#define	INT_VECTOR_COPROC_NOT			0x7
#define	INT_VECTOR_DOUBLE_FAULT			0x8
#define	INT_VECTOR_COPROC_SEG			0x9
#define	INT_VECTOR_INVAL_TSS			0xA
#define	INT_VECTOR_SEG_NOT			0xB
#define	INT_VECTOR_STACK_FAULT			0xC
#define	INT_VECTOR_PROTECTION			0xD
#define	INT_VECTOR_PAGE_FAULT			0xE
#define	INT_VECTOR_COPROC_ERR			0x10

#define	INT_VECTOR_IRQ0				0x20
#define	INT_VECTOR_IRQ8				0x28

// System call vector nr.
#define	INT_VECTOR_SYS_CALL			0x90

#endif

